#include "stdafx.h"
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <fstream>
#include <vector>
#include <iostream>
#include <cassert>
#include <ctime>
#include <cmath>
#include <fstream>
#include <string>
#include "BagOfTasks.h"
//#include "Maths.h"
#include "RayTracer.h"
#include "Maths.h"
#include "KdTreeSimple.h"
#include "OctTreee.h"
#include <vector>
#include <random>
using namespace std;


#pragma region sampleraytracer

struct quickVect
{

   float x,y,z;
   float l;
 };

#define DOT(v1,v2) (v1.x*v2.x + v1.y*v2.y+v1.z*v2.z)
#define CROSS(rez,v1,v2) \
rez.x  = v1.y*v2.z - v1.z*v2.y; \
rez.y  = v1.z*v2.x - v1.x*v2.z; \
rez.z  = v1.x*v2.y - v1.y*v2.x;

#define SUB(rez,v1,v2) \
rez.x = v1.x-v2.x; \
rez.y = v1.y-v2.y; \
rez.z = v1.z-v2.z;


#define LENGTH(v) (sqrtf(v.x* v.x + v.y*v.y + v.z*v.z))

#define NORMALIZE(v) \
v.l = LENGTH(v); \
v.x = v.x / v.l; \
v.y = v.y / v.l; \
v.z = v.z / v.l;

#define EPSILON 0.000001f

//#define TEST_CULL
//void *ReturnedOutput(void *output)
//{
//	BagOfTasksReply<float> *reply = (BagOfTasksReply<float>*)output;
//	Vec3<float> *resultingOutput = (Vec3<float>*) reply->outputResult , *image = resultingOutput;
//	
//	/*std::ofstream ofs("./untitled.ppm", std::ios::out | std::ios::binary);
//	ofs << "P6\n" << reply->width << " " << reply->height << "\n255\n";
//	for (unsigned i = 0; i < reply->width * reply->height; ++i) {
//		ofs << (unsigned char)(min(T(1), image[i].x) * 255) << 
//		(unsigned char)(min(T(1), image[i].y) * 255) <<
//		(unsigned char)(min(T(1), image[i].z) * 255); 
//	}
//	ofs.close();*/
//	delete [] image;
//
//}


//
//struct TestStrucct
//{
//	int number ;
//	explicit TestStrucct(int num = 0) : number(num){}
//};
//
//void *TestInner(void *threadNumber)
//{
//	TestStrucct *index = (TestStrucct*)threadNumber;
//	std::cout << "this is the thread number " << index->number << std::endl;
//	pthread_exit(NULL);
//	return NULL;
//}
//
//void testThreads(int threadAmount)
//{
//	pthread_t threads[100];
//
//	for(int index  = 0; index < threadAmount; index ++)
//	{
//		TestStrucct *currentNumber = new TestStrucct(index);
//		int c = pthread_create(&threads[index], NULL, TestInner, (void *) currentNumber); 	
//	}
//
//}


//pthread_t threads[12];
//int range;
//long *output;
//pthread_t finalWorker;
//bool confimrationArray[12];
//
//void *ExecuteTask(void *task)
//{
//	Task *taskStruct = (Task*) task;
//	int *output = taskStruct->outputArray;
//
//	for(int index = taskStruct->startRange; index <= taskStruct->endRange; index++)
//	{
//		output[index] = index * index;
//	}
//
//	taskStruct->confirmArray[taskStruct->threadIndex] = true;
//	pthread_exit(NULL);
//	return NULL;
//}
//bool checkBoolArray(bool *boolArray, int size)
//{
//	for(int boolIndex = 0; boolIndex < size; boolIndex++)
//	{
//		if(boolArray[boolIndex] == false)
//		{
//			return false;
//		}
//	}
//
//	return true;
//}
//void *ExecuteOutput(void *range)
//{
//	time_t startTimer;
//	time(&startTimer);
//	cout<< "Start timing is " << startTimer<< endl;
//	OutputStruct *outputStruct = (OutputStruct *) range;
//	int *outputArray = outputStruct->output;
//
//	while(checkBoolArray(outputStruct->confitmArray, 12) == false)
//	{
//		//loop here and wait
//	}
//
//	/*for(int index = 0; index <outputStruct->totalRange; index++ )
//	{
//		cout<< outputArray[index] << endl;
//	}*/
//	time_t endTimer;
//	time(&endTimer);
//	std::cout << "End Time " << endTimer << std::endl;
//	std::cout << "elapsed time is : " << endTimer - startTimer << std::endl;
//	delete [] output;
//	pthread_exit(NULL);
//	
//	return NULL;
//}


//
//void SimpleBagOfTasks(int rangeOfNumbers)
//{
//	range = rangeOfNumbers;
//	output = new int[rangeOfNumbers];
//	vector<Task *> bagOfTasks;
//	int numbersPerThreas = rangeOfNumbers / 12;
//	int startRange = 0;
//	for(int threadIndex = 0; threadIndex < 12; threadIndex ++)
//	{
//		int currentEnd = startRange + numbersPerThreas - 1;
//		Task *currentTask = new Task(startRange, currentEnd,threadIndex, output, confimrationArray);
//		startRange = currentEnd + 1;
//		bagOfTasks.push_back(currentTask);
//	}
//
//	OutputStruct *ouptutStruct = new OutputStruct(rangeOfNumbers, output, confimrationArray);
//	pthread_create(&finalWorker, NULL, ExecuteOutput, ouptutStruct);
//
//	for(int taskNumber = 0; taskNumber < 12; taskNumber++)
//	{
//		Task *currentTask = bagOfTasks[taskNumber];
//		pthread_create(&threads[taskNumber], NULL, ExecuteTask, (void *)currentTask);
//	}
//
//	
//}

//void *ReturnedOutput(void *output)
//{
//	BagOfTasksReply<float> *reply = (BagOfTasksReply<float>*)output;
//	Vec3<float> *resultingOutput = (Vec3<float>*) reply->outputResult , *image = resultingOutput;
//		
//	std::ofstream ofs("./untitled.ppm", std::ios::out | std::ios::binary);
//	ofs << "P6\n" << reply->width << " " << reply->height << "\n255\n";
//	for (unsigned i = 0; i < reply->width * reply->height; ++i) {
//		ofs << (unsigned char)(min(float(1), image[i].x) * 255) << 
//		(unsigned char)(min(float(1), image[i].y) * 255) <<
//		(unsigned char)(min(float(1), image[i].z) * 255); 
//	}
//	ofs.close();
//	delete [] image;
//	return NULL;
//}
//
//void ThreadExecute(void *task)
//{
//	RecursiveRayTracingTask<float> *currentTask = (RecursiveRayTracingTask<float>*) task;
//	//continue here
//	Vec3<float> *image = currentTask->outputColection, *pixel = &image[currentTask->startRange];
//	float invWidth = 1 / float(currentTask->width), invHeight = 1 / float(currentTask->height);
//	float fov = 30, aspectratio = currentTask->width / float(currentTask->height);
//	float angle = tan(M_PI * 0.5 * fov / float(180));
//	// Trace rays
//	for (unsigned y = currentTask->startingY; y < currentTask->height; ++y) {
//		for (unsigned x = currentTask->startingX; x < currentTask->width; ++x, ++pixel) {
//			float xx = (2 * ((x + 0.5) * invWidth) - 1) * angle * aspectratio;
//			float yy = (1 - 2 * ((y + 0.5) * invHeight)) * angle;
//			Vec3<float> raydir(xx, yy, -1);
//			raydir.normalize();
//			//*pixel = RecursiveRayTracer<float>::trace(Vec3<float>(0), raydir, currentTask->sphereListPointer, 0);
//		}
//	}
//}
//
//template<typename T>
//T mix(const T &a, const T &b, const T &mix)
//{
//	return b * mix + a * (T(1) - mix);
//}
//
//// This is the main trace function. It takes a ray as argument (defined by its origin
//// and direction). We test if this ray intersects any of the geometry in the scene.
//// If the ray intersects an object, we compute the intersection point, the normal
//// at the intersection point, and shade this point using this information.
//// Shading depends on the surface property (is it transparent, reflective, diffuse).
//// The function returns a color for the ray. If the ray intersects an object that
//// is the color of the object at the intersection point, otherwise it returns
//// the background color.
//template<typename T>
//Vec3<T> trace(const Vec3<T> &rayorig, const Vec3<T> &raydir, 
//	const std::vector<Sphere<T> *> &spheres, const int &depth)
//{
//	//if (raydir.length() != 1) std::cerr << "Error " << raydir << std::endl;
//	T tnear = INFINITY;
//	const Sphere<T> *sphere = NULL;
//	// find intersection of this ray with the sphere in the scene
//	for (unsigned i = 0; i < spheres.size(); ++i) {
//		T t0 = INFINITY, t1 = INFINITY;
//		if (spheres[i]->intersect(rayorig, raydir, &t0, &t1)) {
//			if (t0 < 0) t0 = t1;
//			if (t0 < tnear) {
//				tnear = t0;
//				sphere = spheres[i];
//			}
//		}
//	}
//	// if there's no intersection return black or background color
//	if (!sphere) return Vec3<T>(2);
//	Vec3<T> surfaceColor = 0; // color of the ray/surfaceof the object intersected by the ray
//	Vec3<T> phit = rayorig + raydir * tnear; // point of intersection
//	Vec3<T> nhit = phit - sphere->center; // normal at the intersection point
//	nhit.normalize(); // normalize normal direction
//	// If the normal and the view direction are not opposite to each other 
//	// reverse the normal direction. That also means we are inside the sphere so set
//	// the inside bool to true. Finally reverse the sign of IdotN which we want
//	// positive.
//	T bias = 1e-4; // add some bias to the point from which we will be tracing
//	bool inside = false;
//	if (raydir.dot(nhit) > 0) nhit = -nhit, inside = true;
//	if ((sphere->transparency > 0 || sphere->reflection > 0) && depth < MAX_RAY_DEPTH) {
//		T facingratio = -raydir.dot(nhit);
//		// change the mix value to tweak the effect
//		T fresneleffect = mix<T>(pow(1 - facingratio, 3), 1, 0.1); 
//		// compute reflection direction (not need to normalize because all vectors
//		// are already normalized)
//		Vec3<T> refldir = raydir - nhit * 2 * raydir.dot(nhit);
//		refldir.normalize();
//		Vec3<T> reflection = trace(phit + nhit * bias, refldir, spheres, depth + 1);
//		Vec3<T> refraction = 0;
//		// if the sphere is also transparent compute refraction ray (transmission)
//		if (sphere->transparency) {
//			T ior = 1.1, eta = (inside) ? ior : 1 / ior; // are we inside or outside the surface?
//			T cosi = -nhit.dot(raydir);
//			T k = 1 - eta * eta * (1 - cosi * cosi);
//			Vec3<T> refrdir = raydir * eta + nhit * (eta *  cosi - sqrt(k));
//			refrdir.normalize();
//			refraction = trace(phit - nhit * bias, refrdir, spheres, depth + 1);
//		}
//		// the result is a mix of reflection and refraction (if the sphere is transparent)
//		surfaceColor = (reflection * fresneleffect + 
//			refraction * (1 - fresneleffect) * sphere->transparency) * sphere->surfaceColor;
//	}
//	else {
//		// it's a diffuse object, no need to raytrace any further
//		for (unsigned i = 0; i < spheres.size(); ++i) {
//			if (spheres[i]->emissionColor.x > 0) {
//				// this is a light
//				Vec3<T> transmission = 1;
//				Vec3<T> lightDirection = spheres[i]->center - phit;
//				lightDirection.normalize();
//				for (unsigned j = 0; j < spheres.size(); ++j) {
//					if (i != j) {
//						T t0, t1;
//						if (spheres[j]->intersect(phit + nhit * bias, lightDirection, &t0, &t1)) {
//							transmission = 0;
//							break;
//						}
//					}
//				}
//				surfaceColor += sphere->surfaceColor * transmission * 
//					std::max(T(0), nhit.dot(lightDirection)) * spheres[i]->emissionColor;
//			}
//		}
//	}
//
//	return surfaceColor + sphere->emissionColor;
//}
//
//// Main rendering function. We compute a camera ray for each pixel of the image
//// trace it and return a color. If the ray hits a sphere, we return the color of the
//// sphere at the intersection point, else we return the background color.
//template<typename T>
//void render(const std::vector<Sphere<T> *> &spheres)
//{
//	unsigned width = 640, height = 480;
//	Vec3<T> *image = new Vec3<T>[width * height], *pixel = image;
//	T invWidth = 1 / T(width), invHeight = 1 / T(height);
//	T fov = 30, aspectratio = width / T(height);
//	T angle = tan(M_PI * 0.5 * fov / T(180));
//	// Trace rays
//	for (unsigned y = 0; y < height; ++y) {
//		for (unsigned x = 0; x < width; ++x, ++pixel) {
//			T xx = (2 * ((x + 0.5) * invWidth) - 1) * angle * aspectratio;
//			T yy = (1 - 2 * ((y + 0.5) * invHeight)) * angle;
//			Vec3<T> raydir(xx, yy, -1);
//			raydir.normalize();
//			*pixel = trace(Vec3<T>(0), raydir, spheres, 0);
//		}
//	}
//	// Save result to a PPM image (keep these flags if you compile under Windows)
//	std::ofstream ofs("./untitled.ppm", std::ios::out | std::ios::binary);
//	ofs << "P6\n" << width << " " << height << "\n255\n";
//	for (unsigned i = 0; i < width * height; ++i) {
//		ofs << (unsigned char)(std::min(T(1), image[i].x) * 255) << 
//		(unsigned char)(std::min(T(1), image[i].y) * 255) <<
//		(unsigned char)(std::min(T(1), image[i].z) * 255); 
//	}
//	ofs.close();
//	delete [] image;
//}
//
//int main(int argc, char **argv)
//{
//	srand(13);
//	std::vector<Sphere<float> *> spheres;
//	// position, radius, surface color, reflectivity, transparency, emission color
//	spheres.push_back(new Sphere<float>(Vec3<float>(0, -10004, -20), 10000, Vec3<float>(0.2), 0, 0.0));
//	spheres.push_back(new Sphere<float>(Vec3<float>(0, 0, -20), 4, Vec3<float>(1.00, 0.32, 0.36), 1, 0.5));
//	spheres.push_back(new Sphere<float>(Vec3<float>(5, -1, -15), 2, Vec3<float>(0.90, 0.76, 0.46), 1, 0.0));
//	spheres.push_back(new Sphere<float>(Vec3<float>(5, 0, -25), 3, Vec3<float>(0.65, 0.77, 0.97), 1, 0.0));
//	spheres.push_back(new Sphere<float>(Vec3<float>(-5.5, 0, -15), 3, Vec3<float>(0.90, 0.90, 0.90), 1, 0.0));
//	// light
//	spheres.push_back(new Sphere<float>(Vec3<float>(0, 20, -30), 3, Vec3<float>(0), 0, 0, Vec3<float>(3)));
//	render<float>(spheres);
//	while (!spheres.empty()) {
//		Sphere<float> *sph = spheres.back();
//		spheres.pop_back();
//		delete sph;
//	}
//
//	return 0;
//}

//static vector<Triangle<float>*> ParseObjFile(string path)
//{
//	vector<Vec3<float>> allVertices;
//	vector<Triangle<float>*> allTriangles;
//	string line;
//	ifstream myfile (path);
//	if (myfile.is_open())
//	{
//		while ( getline (myfile,line) )
//		{
//
//			vector<string> tokens;
//			string currentToken = "";
//			for(int index = 0; index <= line.size(); index++)
//			{
//				
//				if( index < line.size() && line[index] != ' ')
//				{
//					currentToken.append(1,line[index]);
//				}
//				else 
//				{
//					tokens.push_back(currentToken);
//					currentToken = "";
//				}
//			}
//				
//			//first token is always what is the type mof the object eg V or F
//			string typeOfLine = tokens[0];
//			if(tokens[0].compare("v") == 0)
//			{
//				float xCoor = atof(tokens[1].c_str());
//				float yCoor = atof(tokens[2].c_str());
//				float zCoor = atof(tokens[3].c_str());
//
//				Vec3<float> currentVector(xCoor, yCoor, zCoor);
//				allVertices.push_back(currentVector);
//			}
//			else if(tokens[0].compare("f") == 0)
//			{
//				int a = (int)atoi(tokens[1].c_str());
//				int b = (int)atoi(tokens[2].c_str());
//				int c = (int)atoi(tokens[3].c_str());
//
//				Vec3<float> coor1 = allVertices[a - 1];
//				Vec3<float> coor2 = allVertices[b - 1];
//				Vec3<float> coor3 = allVertices[c - 1];
//
//				Triangle<float>  *currentTriangle = new Triangle<float>(coor1, coor2, coor3);
//				allTriangles.push_back(currentTriangle);
//				
//			} 
//
//			tokens.clear();
//		}
//
//		myfile.close();
//	}
//	else cout << "Unable to open file"; 
//	return allTriangles;
//}

#pragma endregion

vector<Vec3<float>> CreateRandomPoints(int amount)
{
	vector<Vec3<float>> pointVector;

	for(int x = 0; x < amount; x++)
	{
		float xx = rand() % 2000;
		float y = rand() % 2000;
		float z = rand() % 2000;

		Vec3<float> currentVector(xx, y, z);

		pointVector.push_back(currentVector);
	}

	return pointVector;
}

bool testIntersection(quickVect& v1, quickVect& v2, quickVect& v3, quickVect& orig,quickVect& dir)
{
 quickVect e1,e2,pvec,qvec,tvec;

 SUB(e1,v2,v1);
 SUB(e2,v3,v1);

 CROSS(pvec,dir,e2);

 NORMALIZE(dir);
 //NORMALIZE(pvec);
 float det = DOT(pvec,e1);//b

 if (det < EPSILON && det > -EPSILON )
 {

     return false;
 }

 float invDet = 1.0f / det;
 SUB(tvec,orig,v1);//w0
// NORMALIZE(tvec);
 float u = invDet * DOT(tvec,pvec);
 if (u <0.0f || u > 1.0f)
 {

     return false;
 }
 CROSS(qvec,tvec,e1);
// NORMALIZE(qvec);
 float v = invDet* DOT(qvec,dir);//b


 if (v < 0.0f || u+v > 1.0f)
 {

     return false;
 }
 return true;
}

//bool checkIntersectiokn(Ray<float> * ray, Triangle<float> * triangle)
//{
//	   Vec3<float> edge1 = triangle->vertB - triangle->vertA;
//	   Vec3<float> edge2 = triangle->vertC - triangle->vertA;
//       
//       // Find the cross product of edge2 and the ray direction
//	   Vec3<float> s1 = ray->dir.CrossProduct(edge2);
//       
//       // Find the divisor, if its zero, return false as the triangle is
//       // degenerated
//	   float divisor = s1.dot(edge1);
//       if (divisor == 0.0)
//       {
//             return false;
//       }
//       
//       // A inverted divisor, as multipling is faster then division
//       float invDivisor = 1/ divisor;
//       
//       
//       // Calculate the first barycentic coordinate. Barycentic coordinates
//       // are between 0.0 and 1.0
//	   Vec3<float> distance = ray->orig - triangle->vertA;
//	   float barycCoord_1 = s1.dot(distance) * invDivisor;
//       if (barycCoord_1 < 0.0 || barycCoord_1 > 1.0)
//       {
//                return false;
//       }
//       
//       
//       // Calculate the second barycentic coordinate
//	   Vec3<float> s2 = distance.CrossProduct(edge1);
//	   float barycCoord_2 = ray->dir.dot(edge2) * invDivisor;
//       if (barycCoord_2 < 0.0 || (barycCoord_1 + barycCoord_2) > 1.0)
//       {
//                return false;
//       }
//       
//       // After doing the barycentic coordinate test we know if the ray hits or 
//       // not. If we got this far the ray hits.
//       // Calculate the distance to the intersection point
//	   float intersectionDistance = s2.dot(edge2) * invDivisor;
//       
//     return true;
//}
//
//int intersect3D_RayTriangle( Ray<float> *R, Triangle<float>* T, Vec3<float> &I )
//{
//     Vec3<float>    u, v, n;              // triangle vectors
//     Vec3<float>    dir, w0, w;           // ray vectors
//    float     r, a, b;              // params to calc ray-plane intersect
//
//    // get triangle edge vectors and plane normal
//	u = T->vertB - T->vertA;
//	v = T->vertC - T->vertA;
//    n = u * v;              // cross product
//         // do not deal with this case
//
//	dir = R->dir - R->orig;              // ray direction vector
//	w0 = R->orig - T->vertA;
//	a = n.dot(w0);
//	b =n.dot(dir);
//	if (fabs(b) < EPSILON) {     // ray is  parallel to triangle plane
//        if (a == 0)                 // ray lies in triangle plane
//            return 2;
//        else return 0;              // ray disjoint from plane
//    }
//
//    // get intersect point of ray with triangle plane
//    r = (-a) / b;
//    if (r < 0.0)                    // ray goes away from triangle
//        return 0;                   // => no intersect
//    // for a segment, also test if (r > 1.0) => no intersect
//
//	I = R->orig +  R->dir * r;            // intersect point of ray and plane
//
//    // is I inside T?
//    float    uu, uv, vv, wu, wv, D;
//	uu = u.dot(u);
//    uv = u.dot(v);
//    vv = v.dot(v);
//	w = I - T->vertA;
//	wu = w.dot(u);
//    wv = w.dot(v);
//    D = uv * uv - uu * vv;
//
//    // get and test parametric coords
//    float s, t;
//    s = (uv * wv - vv * wu) / D;
//    if (s < 0.0 || s > 1.0)         // I is outside T
//        return 0;
//    t = (uv * wu - uu * wv) / D;
//    if (t < 0.0 || (s + t) > 1.0)  // I is outside T
//        return 0;
//
//    return 1;                       // I is in T
//}
//
//bool MollerTrumbore_IntersectRayTri(Vec3<float> r_o,Vec3<float> r_d,Vec3<float> v1,Vec3<float> v2,Vec3<float> v3)
//{ Vec3<float> e2=v3-v1;       // second edge
//  Vec3<float> e1=v2-v1;       // first edge
//  Vec3<float> r= r_d.dot(e2);  // (d X e2) is used two times in the formula
//                        // so we store it in an appropriate vector
//  Vec3<float> s=r_o-v1;       // translated ray origin
//  float a=e1.dot(r);    // a=(d X e2)*e1
//  float f=1/a;           // slow division*
//  Vec3<float> q=s.CrossProduct(e1);
//  float u=s.dot(r);
//  bool frontfacing=true;
//  if (a>0)            // eps is the machine fpu epsilon (precision), 
//                        // or a very small number :)
//  { // Front facing triangle...
//    if ((u<0)||(u>a)) return false;
//    float v=r_d.dot(q);
//    if ((v<0)||(u+v>a)) return false;
//  }
//  else if (a<= 0)
//  { // Back facing triangle...
//    frontfacing=false;
//    if ((u>0)||(u<a)) return false;
//	float v=r_d.dot(q);
//    if ((v>0)||(u+v<a)) return false;
//  } else return false; // Ray parallel to triangle plane
//  float t=f*q.dot(e2);
//  u=u*f; 
//  float v = 0;
//  v=v*f;
//  return true;
//}
//
//bool transformer(Ray<float> *ray, Triangle<float> *triangle)
//{
//	quickVect v1,v2, v3, orig, dir;
//	v1.x = triangle->vertA.x;
//	v1.y = triangle->vertA.y;
//	v1.z = triangle->vertA.z;
//
//	v2.x = triangle->vertB.x;
//	v2.y = triangle->vertB.y;
//	v2.z = triangle->vertB.z;
//
//	v3.x = triangle->vertC.x;
//	v3.y = triangle->vertC.y;
//	v3.z = triangle->vertC.z;
//
//	orig.x = 0;
//	orig.y = 0;
//	orig.z = 0;
//
//	dir.x = ray->dir.x;
//	dir.y = ray->dir.y;
//	dir.z = ray->dir.z;
//
//	return testIntersection(v1, v2, v3, orig,dir);
//}


int main(int argc, char **argv)
{
	RayTracer<float> * rayTracer = new RayTracer<float>();
	rayTracer->Execute();
	
	
	////vector<Vec3<float>> listOfPoints = CreateRandomPoints(500);
	//vector<Triangle<float>*> objectMesh = ObjectParser::ParseObjFile("C:\\Users\\Adrian\\Desktop\\teapot.obj",Vec3<float>(5, -1, -15) );
	////bool output = true;

	//////int amount = 500;
	//////vector<Vec3<float>> objectMesh = CreateRandomPoints(50000);
	//////TestKdTree<float> *kdTree = new TestKdTree<float>(objectMesh);
	//KdTree<float> *kdTree = new KdTree<float>(objectMesh);
	//////for(int counter =0; counter  < 50; counter ++)
	//////{
	////	//int toFind = rand() % 500;

	//Triangle<float> * chosenTriangle = objectMesh[50];
	//////
	//Ray<float> *ray = new Ray<float>(Vec3<float>(0), chosenTriangle->GetTrinagleMidpoint()); 
	//ray->dir.normalize();
	//Triangle<float> *testTris;
	//bool output = kdTree->GetIntersection(ray->orig, ray->dir, testTris);
	//////intersecting the triangle with its midpoint
	//Vec3<float> pos;
	////work
	//bool hope = transformer(ray, chosenTriangle);

	//bool test = chosenTriangle->CheckRayIntersection(ray->orig, ray->dir);
	//
	//int underTest = intersect3D_RayTriangle(ray, chosenTriangle, pos);

	////dont work
	//bool secondTest = MollerTrumbore_IntersectRayTri(ray->orig, ray->dir,chosenTriangle->vertA, chosenTriangle->vertB, chosenTriangle->vertC);
	//bool thirdTest = checkIntersectiokn(ray, chosenTriangle);
	////ray = new Ray<float>(Vec3<float>(0), Vec3<float>(2001)); 
	////output = kdTree->CheckIntersection(ray);
	//	//cout << output << "at amount "<< amount<< endl;
	////}
	//
	//delete ray;
	system("pause");
	return 0;
}


